#include "pool_head.h"
#define THREAD_NUMS 4
#define EVS_LEN 10

int pipe_fd[2];
void func(int num){
    write(pipe_fd[1],"1",1);
}

int main(int argc, char* argv[]){
    //创建管道
    pipe(pipe_fd);
    if(fork() != 0){
        close(pipe_fd[0]);
        //注册2号信号
        signal(2,func);
        wait(NULL);
        printf("子进程退出，父进程也退出...\n");
        exit(0);
    }
    //让子进程脱离前台进程组
    setpgid(0,0);
    thread_t thread_s;
    init_pool(&thread_s,THREAD_NUMS);

    int sockfd;
    init_socket(&sockfd,"8080","192.168.52.128");

    int epfd = epoll_create(1);
    ERROR_CHECK(epfd,-1,"epoll_create");

    add_epoll(epfd,sockfd); //将监听连接socket挂到epoll树上
    close(pipe_fd[1]);
    add_epoll(epfd,pipe_fd[0]); //将读端也挂到epoll树上

    struct epoll_event evs[EVS_LEN];
    while(1){
        memset(evs,0,sizeof(evs));
        int num = epoll_wait(epfd,evs,EVS_LEN,-1);
        for(int i = 0; i < num; ++i){
            //取出当前的文件描述符
            int cur_fd = evs[i].data.fd;
            if(cur_fd == sockfd){
                //说明是新连接
                int new_fd = accept(sockfd,NULL,NULL);
                pthread_mutex_lock(&thread_s.lock);
                enqueue(&thread_s.que,new_fd); //将新的连接放到任务队列
                
                //唤醒所有线程
                pthread_cond_broadcast(&thread_s.cond);
                //释放锁
                pthread_mutex_unlock(&thread_s.lock);
            }else{
                //说明管道有数据
                char buf[5] = {0};
                //将数据从管道中读出来
                read(pipe_fd[0],buf,sizeof(buf));

                pthread_mutex_lock(&thread_s.lock); //加锁
                thread_s.exit_flag = 1; //将标志位置为1
                pthread_cond_broadcast(&thread_s.cond);
                pthread_mutex_unlock(&thread_s.lock); //释放锁

                for(int j = 0; j < THREAD_NUMS; ++j){
                    //等待所有子线程退出
                    pthread_join(thread_s.list[j],NULL);
                }
                printf("所有子线程退出，主线程退出...\n");
                pthread_exit(0);
            }
        }
    }
    close(epfd);
    close(sockfd);
    return 0;
}

